#include "Client.h"
#include "Server.h"
#include "GMRequestID.h"
#include "GMRequestTime.h"
#include "GMClientServerPing.h"
#include "Timer.h"

Client::Client() :
m_connected(false),
m_id(-1),
m_time(0.0f),
m_pingCounter(0),
m_delay(0.0f),
m_pingStore(0.0f),
m_numPingSent(0)
{}
bool Client::SendToServer(GameMessage& gm )
{
    return SendGM(gm, &m_sock);
}
bool Client::ConnectToServer( const std::string& IP, int port )
{
    SDLNet_Init();
    GameMessage::StaticPrepareFactory();

    bool ret = m_sock.OpenClient(IP, port);
    if(ret)
    {
        ret = RequestIDFromServer();
    }
    if(ret)
    {
        ret = RequestTimeUpdate();
    }
    m_connected = ret;
    return ret;
}
void Client::ShutDown()
{
    m_connected = false;
    m_sock.Close();
}
bool Client::Listen()
{
    Networking::SockMsg msg;

    if(!m_sock.Receive(&msg))
        return false;

    if(RecvGM(msg))
    {
        OUT_STRING("processed a message..");
    }

    return true;
}
bool Client::RequestIDFromServer()
{
    GMRequestID id;
    return SendToServer(id);
}
int counter = 0;
void Client::Update()
{
    TheTimer::Instance()->Update();
    if(m_connected && !m_sock.IsOpen())
    {
        m_connected = false;
    }
    m_time += TheTimer::Instance()->GetDtMilliSeconds();
    if(m_pingCounter > 0)
    {
        m_pingStore += TheTimer::Instance()->GetDtMilliSeconds();
    }
    Listen();

    counter++;
    if(counter > 60)
    {
        //OUT_STRING("Client Lag: " << m_delay);
        counter = 0;
    }
}
bool Client::PingServer()
{
    if(m_id < 0 || m_pingCounter == 1)
    {
        return true;
    }
    m_pingCounter++;        //
    m_numPingSent++;        //The overall count
    GMClientServerPing gm;
    gm.SetID(m_id);
    bool retVal =  SendToServer(gm);
    if(!retVal)
        m_connected = false;
    return retVal;
}
void Client::AcceptPing(float ts)
{
    m_pingCounter--;
    if(m_pingCounter < 0)
    {
        OUT_STRING("PANIC");
    }
    OUT_STRING("Current Latency: " << m_delay << " New Latency: " << m_pingStore);
    OUT_STRING("Current Timestamp: " << m_time << " ServerClientPing Timestamp: " << ts );
    float diff = m_time - ts;
    OUT_STRING("Time Difference: " << diff);
    m_delay = m_pingStore;
    m_pingStore = 0.0f;
}
bool Client::RequestTimeUpdate()
{
    GMRequestTime timeReq;
    return SendToServer(timeReq);
}

